"""
情感分析算法
"""
import re
import jieba
from typing import Dict, List
from utils.logger import audit_logger
from models.schemas import SentimentAnalysisResult


class SentimentAnalyzer:
    """情感分析器"""
    
    def __init__(self):
        self.positive_words = set()
        self.negative_words = set()
        self.load_sentiment_dict()
    
    def load_sentiment_dict(self):
        """加载情感词典"""
        try:
            # 积极词汇
            positive_words = [
                '好', '棒', '优秀', '喜欢', '开心', '快乐', '满意', '赞', '不错',
                '完美', '精彩', '美好', '温暖', '感谢', '支持', '鼓励', '加油',
                '成功', '胜利', '希望', '幸福', '爱', '友好', '和谐', '积极',
                '正面', '乐观', '自信', '勇敢', '坚强', '努力', '进步', '提升'
            ]
            
            # 消极词汇
            negative_words = [
                '坏', '差', '糟糕', '讨厌', '愤怒', '生气', '难过', '失望', '沮丧',
                '痛苦', '悲伤', '恐惧', '害怕', '担心', '焦虑', '压力', '疲惫',
                '无聊', '烦躁', '抱怨', '批评', '反对', '拒绝', '失败', '错误',
                '问题', '困难', '麻烦', '危险', '威胁', '攻击', '伤害', '破坏'
            ]
            
            self.positive_words = set(positive_words)
            self.negative_words = set(negative_words)
            
            audit_logger.info(f"加载情感词典: 积极词汇{len(self.positive_words)}个, 消极词汇{len(self.negative_words)}个")
            
        except Exception as e:
            audit_logger.error(f"加载情感词典失败: {e}")
    
    def analyze(self, text: str) -> SentimentAnalysisResult:
        """分析文本情感"""
        try:
            if not text:
                return SentimentAnalysisResult(
                    sentiment='neutral',
                    confidence=0.5,
                    score=0.0
                )
            
            # 文本预处理
            cleaned_text = self._preprocess_text(text)
            
            # 分词
            words = jieba.lcut(cleaned_text)
            
            # 计算情感分数
            sentiment_score = self._calculate_sentiment_score(words)
            
            # 确定情感类别
            sentiment, confidence = self._determine_sentiment(sentiment_score, words)
            
            result = SentimentAnalysisResult(
                sentiment=sentiment,
                confidence=confidence,
                score=sentiment_score
            )
            
            if sentiment != 'neutral':
                audit_logger.debug(f"情感分析结果: {sentiment}, 分数: {sentiment_score:.2f}, 置信度: {confidence:.2f}")
            
            return result
            
        except Exception as e:
            audit_logger.error(f"情感分析失败: {e}")
            return SentimentAnalysisResult(
                sentiment='neutral',
                confidence=0.0,
                score=0.0
            )
    
    def _preprocess_text(self, text: str) -> str:
        """文本预处理"""
        # 移除URL
        text = re.sub(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', '', text)
        
        # 移除邮箱
        text = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '', text)
        
        # 移除多余的空白字符
        text = re.sub(r'\s+', ' ', text).strip()
        
        return text
    
    def _calculate_sentiment_score(self, words: List[str]) -> float:
        """计算情感分数"""
        positive_count = 0
        negative_count = 0
        total_words = len(words)
        
        if total_words == 0:
            return 0.0
        
        for word in words:
            if word in self.positive_words:
                positive_count += 1
            elif word in self.negative_words:
                negative_count += 1
        
        # 计算情感分数 [-1, 1]
        if positive_count + negative_count == 0:
            return 0.0
        
        sentiment_score = (positive_count - negative_count) / total_words
        
        # 应用情感强度调整
        sentiment_score = self._apply_intensity_adjustment(words, sentiment_score)
        
        # 限制在[-1, 1]范围内
        return max(-1.0, min(1.0, sentiment_score))
    
    def _apply_intensity_adjustment(self, words: List[str], base_score: float) -> float:
        """应用情感强度调整"""
        # 强化词
        intensifiers = ['很', '非常', '特别', '极其', '超级', '相当', '十分', '格外']
        # 否定词
        negators = ['不', '没', '无', '非', '未', '别', '莫', '勿']
        
        intensity_multiplier = 1.0
        negation_count = 0
        
        for word in words:
            if word in intensifiers:
                intensity_multiplier += 0.3
            elif word in negators:
                negation_count += 1
        
        # 应用强化效果
        adjusted_score = base_score * intensity_multiplier
        
        # 应用否定效果
        if negation_count % 2 == 1:  # 奇数个否定词
            adjusted_score = -adjusted_score
        
        return adjusted_score
    
    def _determine_sentiment(self, score: float, words: List[str]) -> tuple:
        """确定情感类别和置信度"""
        # 基础阈值
        positive_threshold = 0.1
        negative_threshold = -0.1
        
        # 根据情感词密度调整置信度
        sentiment_word_count = sum(1 for word in words if word in self.positive_words or word in self.negative_words)
        word_density = sentiment_word_count / len(words) if words else 0
        
        # 计算置信度
        base_confidence = min(abs(score) * 2, 1.0)  # 基础置信度
        density_bonus = word_density * 0.3  # 密度奖励
        confidence = min(base_confidence + density_bonus, 1.0)
        
        # 确定情感类别
        if score > positive_threshold:
            return 'positive', confidence
        elif score < negative_threshold:
            return 'negative', confidence
        else:
            return 'neutral', max(confidence, 0.5)
    
    def batch_analyze(self, texts: List[str]) -> List[SentimentAnalysisResult]:
        """批量分析文本情感"""
        results = []
        for text in texts:
            result = self.analyze(text)
            results.append(result)
        return results
    
    def get_emotion_distribution(self, text: str) -> Dict[str, float]:
        """获取情感分布"""
        result = self.analyze(text)
        
        if result.sentiment == 'positive':
            return {
                'positive': result.confidence,
                'negative': 1 - result.confidence,
                'neutral': 0.0
            }
        elif result.sentiment == 'negative':
            return {
                'positive': 1 - result.confidence,
                'negative': result.confidence,
                'neutral': 0.0
            }
        else:
            return {
                'positive': 0.0,
                'negative': 0.0,
                'neutral': result.confidence
            }


# 全局情感分析器实例
sentiment_analyzer = SentimentAnalyzer()
